fix: relabel at-or-below-cap data at the capped pixel scale - #431
Merged
Conversation
cap_array_2d_for_small_datasets handled one case and silently dropped the other. Data larger than the 16x16 PYAUTO_SMALL_DATASETS cap was cropped AND rebuilt at SMALL_DATASETS_PIXEL_SCALES (0.6); data already at-or-below the cap early-returned, keeping the caller's uncapped pixel_scales (0.1). A capped simulator writes its data at 0.6, so the loader mislabelled the frame 6x — +/-0.8" instead of +/-4.8" for a 16x16 field. Off-centre galaxies then fell outside the mislabelled frame, their non-negative linear intensity solve correctly returned exactly 0.0, and the resulting collapsed UniformPrior surfaced four steps downstream as a PriorException in autolens_workspace scripts/group/slam.py, naming neither the loader nor the pixel scale. The at-or-below-cap branch now rebuilds the Array2D at the capped scale, mirroring the crop branch. Shape is preserved — that branch must never crop. Rebuilding is required rather than returning a corrected scalar: the Array2D is constructed by the caller before the call and carries its own geometry. Two unit tests asserted the early return as intended behaviour; both are rewritten to assert the relabel-without-cropping. The env-unset test and both crop-path tests are unchanged, guarding the scope of the fix. Fixes #430 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
cap_array_2d_for_small_datasetshandled one case and silently dropped the other. Data larger than the 16x16PYAUTO_SMALL_DATASETScap was cropped and rebuilt atSMALL_DATASETS_PIXEL_SCALES(0.6); data already at-or-below the cap early-returned, keeping the caller's uncappedpixel_scales(0.1). A capped simulator writes its data at 0.6, so the loader mislabelled the frame 6x — ±0.8" instead of ±4.8" for a 16x16 field.Off-centre galaxies then fell outside the mislabelled frame, their non-negative linear intensity solve correctly returned exactly 0.0,
total_luminositybecame 0, andmin(5 * 0.5 * 0**0.6, 5.0)collapsed aUniformPriortolower == upper == 0.0. ThePriorExceptionsurfaced four steps downstream inautolens_workspace/scripts/group/slam.py:321, naming neither the loader nor the pixel scale.The at-or-below-cap branch now rebuilds the
Array2Dat the capped scale, mirroring the crop branch. Shape is preserved — that branch must never crop. Rebuilding is required rather than returning a corrected scalar: theArray2Dis constructed by the caller before the call and carries its own geometry.Fixes #430. Fixes the
group/slam.py+group/slam.ipynbfailures in PyAutoHeart Workspace Smoke run 30790463134.API Changes
No signature changes. One behaviour change, confined to runs with
PYAUTO_SMALL_DATASETS=1:autoarray.util.dataset_util.cap_array_2d_for_small_datasetsnow returnsSMALL_DATASETS_PIXEL_SCALES(0.6) and a rebuiltArray2Dfor input already at-or-below the cap, where it previously returned the caller'spixel_scalesand the input array untouched. Shape is unchanged in that branch. Reached in practice throughImaging.from_fits, which routesdataandnoise_map(notpsf) through it.With the cap unset — every normal run — behaviour is byte-identical, and the crop branch is untouched.
See full details below.
Test Plan
pytest test_autoarray/— 929 passedscripts/group/slam.py(autolens_workspace) under the capped smoke profile, cleared dataset + output → exit 0, all six SLaM stages genuinely run (0 cached resumes; note output is namespaced underoutput/test_mode/)cosmos_web_ringgives(16,16) @ 0.6identically before and afterscripts/imaging/start_here.py(ENV: full_datasets) exit 0slacs1430+4105/psf.fits, 11x11) and PSFs never route through the capper — so no committed dataset changes scaleDownstream effect on two parked scripts
imaging/features/scaling_relation/slam→ now exit 0 (6 real searches). ItsNEEDS_FIXpark inautolens_workspace/config/build/no_run.yamlcan be removed in a separate workspace PR.multi_galaxy/features/scaling_relation/slam→ gets past the 0.0-luminosity cause (real luminosities now measured) but then hits a separate latent script bug:slam.py:863computesimage_half_widthfrom the script's own hardcodedpixel_scale(0.1) while the mask is built fromdataset_full.pixel_scales(now correctly 0.6), producing an empty mask. Not a regression — on unpatchedmainit fails earlier with the documented 0.0-luminosity error. Stays parked; filed separately.Full API Changes (for automation & release notes)
Changed Behaviour
autoarray.util.dataset_util.cap_array_2d_for_small_datasets(array_2d, pixel_scales)— whenPYAUTO_SMALL_DATASETS=1andarray_2d.shape_nativeis at-or-belowSMALL_DATASETS_SHAPE_NATIVE, now returns a rebuiltArray2DatSMALL_DATASETS_PIXEL_SCALESand that scale, instead of returning the inputs unchanged. Shape preserved; no cropping in this branch. Unchanged when the env var is unset, and unchanged for above-cap input.Removed
Added
Migration
pixel_scales(the documented contract, and whatImaging.from_fitsdoes) need no change. Code that ignored the returnedpixel_scalesand reused its own literal was already relying on the buggy path under the cap; it should consume the returned value or readdataset.pixel_scales.Generated by the PyAutoLabs agent workflow.